package generador_de_codigo;

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;



public class GeneradorDeCodigo {
	
    private static FileWriter fstream;;
    private static BufferedWriter out;
    public static boolean has_main;
    private static int etiqueta;
	
    public static void crearArchivo(String destino){
        try {
            fstream = new FileWriter(destino);
            has_main = false;
        } catch (IOException ex) {
            Logger.getLogger(GeneradorDeCodigo.class.getName()).log(Level.SEVERE, null, ex);
        }
        out = new BufferedWriter(fstream);
        
    }
    
	public static void inicializar() throws IOException
	{
		etiqueta = 0;
                
                generar(" .CODE \n");
                generar("Push simple_heap_init \n");
                generar("CALL \n");   
                generar("PUSH metodo_main \n");
                generar("CALL \n");
		generar("HALT \n");
                generarInit();
                generarObject();
		generarSystem();
	}
		
	private static void generarObject()throws IOException
	{	
		out.write("Object_Ctor: LOADFP\n");
		out.write("LOADSP\n");
		out.write("STOREFP\n");
		out.write("STOREFP\n");
		out.write("RET 1\n");
	}
	
	private static void generarSystem()throws IOException
	{
		
		// Constructor
		out.write("System_Ctor: LOADFP\n");
		out.write("LOADSP\n");
		out.write("STOREFP\n");
		out.write("STOREFP\n");
		out.write("RET 1\n");
		
		// int read()
		out.write("System_read: LOADFP\n");
		out.write("LOADSP\n");
		out.write("STOREFP\n");
		out.write("READ\n");
                out.write("STORE 3\n");
		out.write("STOREFP\n");
		out.write("RET 0\n");
		
		// printB(c)
		out.write("System_printB: LOADFP\n");
		out.write("LOADSP\n");
		out.write("STOREFP\n");
		out.write("LOAD 3\n");
		out.write("BPRINT\n");
		out.write("STOREFP\n");
		out.write("RET 1\n");
		
		// printC(c)
		out.write("System_printC: LOADFP\n");
		out.write("LOADSP \n");
		out.write("STOREFP \n");
		out.write("LOAD 3 \n");
		out.write("CPRINT \n");
		out.write("STOREFP \n");
		out.write("RET 1 \n");
		
		// printI(c)
		out.write("System_printI: LOADFP \n");
		out.write("LOADSP \n");
		out.write("STOREFP \n");
		out.write("LOAD 3 \n");
		out.write("IPRINT \n");
		out.write("STOREFP \n");
		out.write("RET 1 \n");
		
		// printS(c)
		out.write("System_printS: LOADFP\n");
		out.write("LOADSP\n");
		out.write("STOREFP\n");
		out.write("LOAD 3\n");
		out.write("SPRINT\n");
		out.write("STOREFP\n");
		out.write("RET 1\n");
		
		// println()
		out.write("System_println: LOADFP\n");
		out.write("LOADSP\n");
		out.write("STOREFP\n");
		out.write("PRNLN\n");
		out.write("STOREFP\n");
		out.write("RET 0\n");
		
		// printBln(c)
		out.write("System_printBln: LOADFP\n");
		out.write("LOADSP\n");
		out.write("STOREFP\n");
		out.write("LOAD 3\n");
		out.write("BPRINT\n");
		out.write("PRNLN\n");
		out.write("STOREFP\n");
		out.write("RET 1\n");
		
		// printCln()
		out.write("System_printCln: LOADFP\n");
		out.write("LOADSP\n");
		out.write("STOREFP\n");
		out.write("LOAD 3\n");
		out.write("CPRINT\n");
		out.write("PRNLN\n");
		out.write("STOREFP\n");
		out.write("RET 1\n");
		
		// printIln(c)
		out.write("System_printIln: LOADFP\n");
		out.write("LOADSP\n");
		out.write("STOREFP\n");
		out.write("LOAD 3\n");
		out.write("IPRINT\n");
		out.write("PRNLN\n");
		out.write("STOREFP\n");
		out.write("RET 1\n");
		
		// printSln()
		out.write("System_printSln: LOADFP\n");
		out.write("LOADSP\n");
		out.write("STOREFP\n");
		out.write("LOAD 3\n");
		out.write("SPRINT\n");
		out.write("PRNLN\n");
		out.write("STOREFP\n");
		out.write("RET 1\n");
	}

        public static void generar(String gen) throws IOException{
            out.write(gen);
        }
	
        public static String generarEtiqueta(String gen) throws IOException{
            return gen+etiqueta++;
            
        }
        
        public static void cerrarArchivo() throws IOException{
            out.close();
        }

    private static void generarInit() throws IOException {
    //    out.write(".CODE \n");
        out.write("simple_heap_init: RET 0 \n");

        out.write("simple_malloc:");
	out.write(" LOADFP	; Inicialización unidad	\n");
	out.write("LOADSP \n");
	out.write("STOREFP ; Finaliza inicialización del RA \n");
	out.write("LOADHL	; hl \n");
	out.write("DUP	; hl \n");
	out.write("PUSH 1	; 1 \n");
	out.write("ADD	; hl+1 \n");
	out.write("STORE 4 ; Guarda el resultado (un puntero a la primer celda de la región de memoria) \n");
 	out.write("LOAD 3	; Carga la cantidad de celdas a alojar (parámetro que debe ser positivo) \n");
	out.write("ADD \n");
	out.write("STOREHL ; Mueve el heap limit (hl). Expande el heap \n");
	out.write("STOREFP \n");
	out.write("RET 1	; Retorna eliminando el parámetro \n");
    }
}
